/**
 * ***********************************************************************
 * Client.java
 * Universidad del Valle de Guatemala
 * Algoritmos y Estructura de Datos
 * @autor Martín Guzmán, Karen Tojín, Jeffry Turcios, David Coronado
 * Fecha: 30 de noviembre de 2009
 * ************************************************************************
 */
/**
 * Descripción: Clase CLIENTE, tienes las peticiones que le cliente puede realizar.
 */
import org.jdom.*;
import java.util.*;
import java.net.*;
import java.io.*;

public class Client {

    public static boolean error = false;
    private static int hacer;
    private static int opciones_del_menu = 0;
    private static Scanner scan = new Scanner(System.in);
    private static String peticion = "";
    private static boolean mal_ingreso = false;

    /**
     * Método principar que maneja el sistema en la parte del cliente
     * @param args[]
     */
    public static void main(String args[]) throws IOException, ClassNotFoundException {
        System.out.println("\n********************************************************\n");
        System.out.println("     Bienvenido al sistema cliente/servidor\n");
        System.out.println("*********************************************************");

        //ciclo para repetir hasta que quiera salir del programa
        do {
            Menu();
            if (mal_ingreso == false) {
                Continuar();
            }

        } while (hacer != opciones_del_menu);//hasta que precione salir
        System.out.println("\n\n¡Gracias por utilizar el programa!");
    }

    /**
     * Método que evalúa la acción decidida por el cliente
     * @param instruction: la isntrucción enviada por el cliente
     */
    public static Document XMLwriter(String instruction) {

        Element root = new Element(instruction.split(" ")[0]);

        if (instruction.split(" ")[0].equals("ingresar")) {
            Element nombre = new Element("nombre");
            nombre.setText(instruction.split(" ")[2]);
            Element apellido = new Element("apellido");
            apellido.setText(instruction.split(" ")[3]);
            Element carnet = new Element("carnet");
            carnet.setText(instruction.split(" ")[1]);
            Element carrera = new Element("carrera");
            carrera.setText(instruction.split(" ")[4]);

            root.addContent(carnet);
            root.addContent(nombre);
            root.addContent(apellido);
            root.addContent(carrera);

        } else if (instruction.split(" ")[0].equals("modificar")) {
            Element carnet = new Element("carnet");
            carnet.setText(instruction.split(" ")[1]);
            Element campo_modificar = new Element(instruction.split(" ")[2]);
            campo_modificar.setText(instruction.split(" ")[3]);

            root.addContent(carnet);
            root.addContent(campo_modificar);
        } else if (instruction.split(" ")[0].equals("borrar")) {
            Element carnet = new Element("carnet");
            carnet.setText(instruction.split(" ")[ 1]);

            root.addContent(carnet);
        } else if (instruction.split(" ")[0].equals("buscar")) {
            Element campo_buscar = new Element(instruction.split(" ")[1]);
            campo_buscar.setText(instruction.split(" ")[2]);

            root.addContent(campo_buscar);
        } else {
            System.out.println("Error en peticion. Escriba la peticion de nuevo");
            error = true;
        }

        Document doctemp = new Document(root);
        return doctemp;
    }

    /**
     * Método que despliega el menú para realizar la acción del cliente
     */
    public static void Menu() {
        mal_ingreso = false;
        do //ciclo hasta que ingrese bien una acción a realizar
        {
            opciones_del_menu = 0;

            System.out.println("\n\t************* Menu Principal de base de datos *************\n");
            System.out.println("1- Ingresar registro");
            opciones_del_menu++;
            System.out.println("2- Modificar registro");
            opciones_del_menu++;
            System.out.println("3- Eliminar registro");
            opciones_del_menu++;
            System.out.println("4- Buscar registro");
            opciones_del_menu++;
            System.out.println("5- Salir");
            opciones_del_menu++;
            System.out.print("\t¿Qué desea hacer?\tMarque el número: ");
            //despliega mensaje de error si no escoje una opcion del menu principal
            try {
                hacer = scan.nextInt();
            } catch (Exception exp) { //para prevenir el ingreso de algún caracter diferente a número
                System.out.println("¡Error acción no válida!\n");
                hacer = -1;
            }
            scan.nextLine();
            if ((hacer < 1 || hacer > opciones_del_menu) && (hacer != -1)) {
                System.out.println("¡Error acción fuera de las opciones!\n");
            }

        } while (hacer < 1 || hacer > opciones_del_menu);
        System.out.println("\n*************************************************************\n");

        //para realizar la accion marcada arriba
        switch (hacer) {
            case 1://  ********** Ingresar registro ****************************
                System.out.println("Ingrese utilizando el siguiente formato: carnet nombre apellido carrera\n\t >> Por ejemplo: 08091 Karen Tojin Computación");
                String temp1 = scan.nextLine();

                // verificar dobles espacios en blanco
                while (temp1.contains("  ")) {
                    temp1 = temp1.replaceAll("  ", " ");
                }

                // cambiar por comas
                temp1 = temp1.replaceAll(" ", ",");
                // ver que no empiece con una coma
                if (temp1.startsWith(",")) {
                    temp1 = temp1.substring(1, temp1.length());
                }

                //ver que no termine con una coma
                if (temp1.endsWith(",")) {
                    temp1 = temp1.substring(0, temp1.length() - 1);
                }

                // validar caso ingreso
                String[] arreglo_temp_1 = temp1.split(",");

                // verificar el tamaño correcto
                if (arreglo_temp_1.length != 4) {
                    System.out.println("\n\t >> Error. La cantidad de elementos que ingresó es incorrecta");
                    mal_ingreso = true;
                    break;
                }
                //incluir el inicio
                peticion = "ingresar ";
                //anexar el contenido
                for (int i = 0; i < arreglo_temp_1.length; i++) {
                    //System.out.println("A: "+arreglo_temp_1[i]);
                    peticion += arreglo_temp_1[i] + " ";
                }
                peticion = peticion.substring(0, peticion.length() - 1);

                break;
            case 2://  ********** Modificar registro ***************************

                System.out.println("Ingrese utilizando el siguiente formato: carnet campo_a_modificar modificación\n\t >> Por ejemplo: 08091 carrera Biología");
                System.out.println("Puede seleccionar entre los siguientes campos: nombre, apellido, carrera");
                String temp2 = scan.nextLine();

                // verificar dobles espacios en blanco
                while (temp2.contains("  ")) {
                    temp2 = temp2.replaceAll("  ", " ");
                }

                // cambiar por comas
                temp2 = temp2.replaceAll(" ", ",");
                // ver que no empiece con una coma
                if (temp2.startsWith(",")) {
                    temp2 = temp2.substring(1, temp2.length());
                }

                //ver que no termine con una coma
                if (temp2.endsWith(",")) {
                    temp2 = temp2.substring(0, temp2.length() - 1);
                }

                // validar caso ingreso
                String[] arreglo_temp_2 = temp2.split(",");


                // verificar el tamaño correcto
                if (arreglo_temp_2.length != 3) {
                    System.out.println("\n\t >> Error. La cantidad de elementos que ingresó es incorrecta");
                    mal_ingreso = true;
                    break;
                }

                if (!(arreglo_temp_2[1].compareToIgnoreCase("carrera") == 0) && !(arreglo_temp_2[1].compareToIgnoreCase("nombre") == 0) && !(arreglo_temp_2[1].compareToIgnoreCase("apellido") == 0)) {
                    System.out.println("\n\t >> Error. No ingresó correctamente un campo para la modificación");
                    mal_ingreso = true;
                    break;
                }

                //incluir el inicio
                peticion = "modificar ";
                //anexar el contenido
                for (int i = 0; i < arreglo_temp_2.length; i++) {
                    //System.out.println("A: "+arreglo_temp_1[i]);
                    peticion += arreglo_temp_2[i] + " ";
                }
                peticion = peticion.substring(0, peticion.length() - 1);

                break;
            case 3://  ********** Eliminar registro ****************************

                System.out.println("Ingrese el carnet del registro que desea eliminar");
                String temp3 = scan.nextLine();

                // verificar dobles espacios en blanco
                while (temp3.contains("  ")) {
                    temp3 = temp3.replaceAll("  ", " ");
                }

                // cambiar por comas
                temp3 = temp3.replaceAll(" ", ",");
                // ver que no empiece con una coma
                if (temp3.startsWith(",")) {
                    temp3 = temp3.substring(1, temp3.length());
                }

                //ver que no termine con una coma
                if (temp3.endsWith(",")) {
                    temp3 = temp3.substring(0, temp3.length() - 1);
                }

                // validar caso ingreso
                String[] arreglo_temp_3 = temp3.split(",");

                // verificar el tamaño correcto
                if (arreglo_temp_3.length != 1) {
                    System.out.println("\n\t >> Error. La cantidad de elementos que ingresó es incorrecta");
                    mal_ingreso = true;
                    break;
                }

                //incluir el inicio
                peticion = "borrar ";
                //anexar el contenido
                for (int i = 0; i < arreglo_temp_3.length; i++) {
                    //System.out.println("A: "+arreglo_temp_1[i]);
                    peticion += arreglo_temp_3[i] + " ";
                }
                peticion = peticion.substring(0, peticion.length() - 1);
                break;
            case 4://  ********** Buscar registro ******************************
                System.out.println("Ingrese su búsqueda utilizando el siguiente formato: campo_en_el_que_buscar elemento\n\t >> Por ejemplo: nombre Luis");
                System.out.println("Puede seleccionar entre los siguientes campos: carne, apellido, carrera");
                String temp4 = scan.nextLine();

                // verificar dobles espacios en blanco
                while (temp4.contains("  ")) {
                    temp4 = temp4.replaceAll("  ", " ");
                }

                // cambiar por comas
                temp4 = temp4.replaceAll(" ", ",");
                // ver que no empiece con una coma
                if (temp4.startsWith(",")) {
                    temp4 = temp4.substring(1, temp4.length());
                }

                //ver que no termine con una coma
                if (temp4.endsWith(",")) {
                    temp4 = temp4.substring(0, temp4.length() - 1);
                }

                // validar caso ingreso
                String[] arreglo_temp_4 = temp4.split(",");

                // verificar el tamaño correcto
                if (arreglo_temp_4.length != 2) {
                    System.out.println("\n\t >> Error. La cantidad de elementos que ingresó es incorrecta");
                    mal_ingreso = true;
                    break;
                }

                if (!(arreglo_temp_4[0].compareToIgnoreCase("carrera") == 0) && !(arreglo_temp_4[0].compareToIgnoreCase("nombre") == 0) && !(arreglo_temp_4[0].compareToIgnoreCase("apellido") == 0) && !(arreglo_temp_4[0].compareToIgnoreCase("carnet") == 0)) {
                    System.out.println("\n\t >> Error. No ingresó correctamente un campo para la búsqueda");
                    mal_ingreso = true;
                    break;
                }

                //incluir el inicio
                peticion = "buscar ";
                //anexar el contenido
                for (int i = 0; i < arreglo_temp_4.length; i++) {
                    //System.out.println("A: "+arreglo_temp_1[i]);
                    peticion += arreglo_temp_4[i] + " ";
                }
                peticion = peticion.substring(0, peticion.length() - 1);
                break;
        }
    }
    /**
     * Método que realiza la conexión con el servidor por medio de sockets
     * @throws ClassNotFoundException
     */
    private static void Continuar() throws ClassNotFoundException {

        Scanner input = new Scanner(System.in);

        Document doc = XMLwriter(peticion);

        try {

            //ip donde se encuentra el servidor
            System.out.println("\n\n--------------------------------------------------------------------------------");
            Socket s1 = new Socket("192.168.61.47", 5432);

            //System.out.println("Mi IP: "+s1.getLocalAddress());
            InputStream is = s1.getInputStream();

            ObjectOutputStream dos = new ObjectOutputStream(s1.getOutputStream());

            // *****************************************************************
            // envia el objeto Document
            // *****************************************************************
            dos.writeObject(doc);

            ObjectInputStream dis = new ObjectInputStream(is);

            // *****************************************************************
            // espera respuesta del servidor
            // *****************************************************************
            System.out.println("Respuesta del servidor: " + (String) dis.readObject());

            s1.close();
            dis.close();
        } catch (ConnectException connExc) {
            System.err.println("OCURRIÓ UN ERROR CON EL SERVIDOR");
        } catch (IOException e) {
        }
    }
}
